import {apiArr, v} from '../api/001'
const _getHttp = Symbol('_getHttp'),
    _login = Symbol('_login'),
    _getSo = Symbol('_getSo')
export default class Controller {
    static fnArr = []
    static funcretdata={
        isCall: false,
        succ:function(){},
        fail:function(){}
    }
    static paramsObj={}
    loginData = {
        userData: { member_id: 0 },
    }
    userLoginStatus = {            //用户登录状态数据
        leaveType: 0,              //0.初始化  1 .被踢下线   2. socket断开 
        isOnLine: false,           //true在线  ,  false 离线
        userSelect: 0,             //0.没有选择 ，1.继续连接  2.不连接
        timeOff: '',               //定时器开关
    }
    constructor(socket, config) {
        this.socket = socket;
        this.config = config;
        let storageConfig = sessionStorage.getItem('config')
        if(storageConfig){
            storageConfig = JSON.parse(storageConfig)
            this.config = storageConfig
        }
        Controller.fnArr = apiArr
        console.log(`api版本号：${v}`)
    }
    /* 初始化属性 */
    setProperty(member_id, token, key, h_url, a_url, e_url) {
        this.member_id = member_id;
        this.token = token;
        this.key = key;
        this.h_url = h_url;
        this.a_url = a_url;
        this.e_url = e_url;
    }
    action(fnName, params, succCallback=null, failCallback=null) {
        // 验证方法名
        let fn = null
        Controller.fnArr.find(item => { if(item.fnName == fnName){fn = item} })
        if (!fn) { return failCallback({ code: 301, data: `${fnName}方法不存在！` }) }
        //  解析需传参数
        let paramsType = (fn.params instanceof Array);
        (!paramsType && fn.params !=='') ? fn.params = fn.params.split(',') : null;
        (!paramsType && fn.params =='') ? fn.params = [] : null;
        const paramsList = [];
        //验证参数
        let loseKey = null
        loseKey = fn.params.find((item) => { if (!params[item] && !params.noMust) { loseKey=item } paramsList.push(params[item])  })
        if (loseKey) {
            const data = { code: 301, data: fnName + '函数缺少' + loseKey + '参数!' };
            failCallback && failCallback(data);
        }

        Controller.funcretdata.succ = succCallback
        Controller.funcretdata.fail = failCallback
        Controller.funcretdata.isCall = false
        Controller.paramsObj = params
        this[fnName](...paramsList, succCallback, failCallback);
    }
    onSucc(data){
        // console.log(Controller.funcretdata.isCall,Controller.funcretdata.succ)
        if(Controller.funcretdata.isCall == true){
            console.log('程序出错，回调函数已经被调用过')
        }
        Controller.funcretdata.isCall = true
        Controller.funcretdata.succ(data)
        
    }
    onFail(data){
        if(Controller.funcretdata.isCall == true){
            console.log('程序出错，回调函数已经被调用过')
        }
        Controller.funcretdata.isCall = true 
        Controller.funcretdata.fail(data)
        
    }
    /* 清理属性 */
    clear(){
        this.member_id = ''
        this.token = ''
        this.key = ''
        this.h_url = ''
        this.a_url = ''
        this.e_url = ''
    }
    /*(测试)断开连接*/
    loginOut() {
        this.socket.so.close();
        this.socket.so = null;
    }
    /*判断登录状态*/
    readyStateLogin() {
        let i = setInterval(() => {
            if (this.userLoginStatus.isOnLine) {
                clearInterval(i);
                return this.onSucc();
            }
        }, 1000);
    }
    /*socket实例*/
    setConfig() {
        let option = Controller.paramsObj.option
        const required = ['h_url', 'a_url', 'e_url', 'port', 'sertype', 'onLoginSuccess', 'onCloseCallback'];
        let falg = null
        required.find(key => {
            if (!option[key] && key) { falg = key }
        })
        if (typeof option.onLoginSuccess != "function") { return this.onFail({code: 301, data:"onLoginSuccess 必需为函数！" }) }
        if (falg) {return this.onFail({code:301,data:`${falg}字段缺失!` } ) }
        this.loginData = { ...this.loginData, ...option };
        this.config = option;
        this.socket.storage.saveBySessionStorage('config', this.config)
    }
    /*用户快速连接*/
    quickConnect() {
        let {key, token, member_id, port} = Controller.paramsObj
        this.loginData.userData.member_id = member_id;
        this.loginData.key = key;
        this.loginData.token = token;
        this.socket.storage.saveBySessionStorage('loginData',{key:key,token:token,member_id:member_id,port:port})
        this[_login]('', '', key, token)
        this.loginData.userData.port = port ? port : this.loginData.userData.port;
        this.setProperty(member_id, token, key, this.config.h_url, this.config.a_url, this.config.e_url)
    }
    /*发送会话消息*/
    sendTalkMsg() {
        let params = arguments[0];
        (params instanceof Object) == true ? Controller.paramsObj = params : Controller.paramsObj
        let {talk_id, content, type} = Controller.paramsObj
        if (!talk_id || !content || !type) {return this.onFail({code:301,data:'发送会话消息 缺少参数！'}) }
        const ret = this.socket.sendController.sendServerMsg("talk", { content: content, talk_id: Number(talk_id), type: type }, this.member_id, this.onSucc, this.onFail)
        if (ret.code != 200) {return this.onFail({code:301,data: ret.data}) }
    }
    /*创建临时会话*/
    makeDialogue() {
        let {title, toMemberId, content} = Controller.paramsObj
        if (!title || !toMemberId) {
            return this.onFail({ code: 301, data: "参数缺失！"})
        }
        if (toMemberId == this.member_id) {
            return this.onFail({ code: 301, data: "toMemberId 和 用户MemberId 相同！"});
        }
        if (typeof content != 'object') {
            return this.onFail({ code: 301, data: 'content 必须为 对象类型！' })
        }
        content = JSON.parse(JSON.stringify(content))
        var token = this.token;
        this[_getHttp](this.h_url + "/makeTemporaryTalk", { title, token, toMemberId },
            data => {
                if (data.code == 200) {
                    this.socket.sendController.sendServerMsg("makeTemporaryTalk", { dialogueKey: data.data.dialogueKey }, toMemberId, (res) => {
                        this.sendTalkMsg({talk_id:res.body.data.talk.id, content:content, type:2})
                        return this.onSucc(res);
                    }, Controller.funcretdata.fail);
                } else {
                    return this.onFail({ code: 301, data: data.data})
                }
            }
        );
    }
    /*更改用户头像*/
    editAvatarurl() {
        let {file} = Controller.paramsObj
        let xmlpost = new XMLHttpRequest();
        let url = this.a_url + '/editAvatarurl?key=' + this.key;
        let formdata = new FormData();
        formdata.append('file', file);
        xmlpost.open("post", url, true);
        xmlpost.send(formdata);
        xmlpost.onreadystatechange = () => {
            if (xmlpost.readyState == 4 && xmlpost.status == 200) {
                this.socket.sendController.sendServerMsg('refreshInEditSelfInfo', {}, this.member_id,this.onSucc,this.onFail);
            }else {
                return this.onFail({code: 301, data: '更换失败'});
            }
        }
      /*   this[_getHttp](url, {key:formdata},(data)=>{
            if(data.code == 200){
                console.log(data)
            }
        }) */
    }
    /*更改用户姓名*/
    editSelfName() {
        let {name} = Controller.paramsObj
        if (!name) { return this.onFail({code: 301, data: '用户名为空'}); }
        let url = this.a_url + '/editSelfName';
        this[_getHttp](url, { name, key: this.key }, (data) => {
            if (data.code == 200){
                this.socket.sendController.sendServerMsg('refreshInEditSelfInfo', {}, this.member_id, this.onSucc, this.onFail);
            }
        });
    }
    /*跟据用户id添加好友*/
    addFriendUseMemberId() {
        let {member_id} = Controller.paramsObj 
        this.socket.sendController.sendServerMsg('addFriendUseMemberId', { member_id: Number(member_id) }, this.member_id, this.onSucc,this.onFail);  
    }
    /*跟据临时会话id添加好友*/
    addFriendUseTalkId() {
        let {talk_id} = Controller.paramsObj
        this.socket.sendController.sendServerMsg('addFriendUseTalkId', { talk_id: Number(talk_id) }, this.member_id, this.onSucc,this.onFail);      
    }
    /*审核添加好友*/
    examineToFriend() {
        let {clientMsgId, userSelect} = Controller.paramsObj
        //找到好友请求  
        const res = this.socket.friendObject.resolveAgree(clientMsgId);
        if (res.code != 200) { return this.onFail({code: 301, data: res.data}); }
        // 'fromType'=> '1临时会话，2手机号，3群聊',
        //验证参数
        if (userSelect != 1 && userSelect != -1) {return this.onFail({ code: 301, data: 'userSelect 格式错误！' }) }
        this.socket.sendController.sendServerMsg('examineToFriend', {oliveBranchKey: res.data.body.oliveBranchKey,type: userSelect}, this.member_id, this.onSucc,this.onFail);
    }
    /*删除好友*/
    deleteFriend() {
        let {talk_id} = Controller.paramsObj
        if (!talk_id) { talk_id = prompt("输入talk_id") }
        this.socket.sendController.sendServerMsg('delFriend', { talk_id }, this.member_id, this.onSucc,this.onFail)
    }
    /*通过手机号搜索用户*/
    findFriendFromTel() {
        let {tel} = Controller.paramsObj
        if (!tel) { tel = prompt("输入手机号.") }
        this.socket.sendController.sendServerMsg('findFriendFromTel', { tel }, this.member_id, this.onSucc,this.onFail);
    }
    /*获取好友申请列表*/
    fetchFriendApplyList() {
        let ret = this.socket.friendObject.getAppList();
        if(ret.code == 200){
            return this.onSucc(ret)
        }
    }
    /*退出会话*/
    exitTalk() {
        let ret = this.socket.talkObject.exitTalk();
        if(ret.code == 200){
            return this.onSucc(ret)
        }
    }
    /*talkObject添加回调函数*/
    addTalkObjectCallback() {
        let {onNewChatAlert, onListRefresh, onTalkDetailRefresh, onTalkWithMsg} = Controller.paramsObj
        let ret = this.socket.talkObject.addCallBack(onNewChatAlert, onListRefresh, onTalkDetailRefresh, onTalkWithMsg)
        if(ret.code == 200){
            return this.onSucc(ret)
        }
    }
    /*取会话列表*/
    getTalkList() {
        let ret = this.socket.talkObject.getTalkList()
        if(ret.code == 200){
            return this.onSucc(ret)
        }
    }
    /*取会话信息*/
    getTalkDetail() {
        let {talk_id} = Controller.paramsObj
        let ret = this.socket.talkObject.getTalkDetail(talk_id)
        if(ret.code == 200){
            return this.onSucc(ret)
        }
    }
    /*取会话聊天记录*/
    getChat() {
        let {talk_id} = Controller.paramsObj
        let ret = this.socket.talkObject.getChat(talk_id)
        if(ret.code == 200){
            return this.onSucc(ret)
        }
    }
    /* 请求处理 */
    [_getHttp](url, params, callback) {
        for (let i in arguments) {
            if (arguments[i] == undefined || arguments[i] == '') {
                return callback("getHttp参数，第 " + i + "个参数不能为空！")
            }
        }
        var xmlpost = new XMLHttpRequest();
        xmlpost.open("post", url, true);
        var postData = [];
        if (params) {
            for (let i in params) {
                postData.push(i + "=" + params[i]);
            }
            postData = postData.join("&");
        }
        xmlpost.send(postData);
        xmlpost.onreadystatechange = function () {
            if (xmlpost.readyState == 4) {
                if (xmlpost.status == 200) {
                    var data = JSON.parse(xmlpost.responseText);
                    return callback(data);
                }else{
                    return callback(`请求出错${xmlpost}`)
                }
            }
        };
    }
    /*登录*/
    [_login](username, password, key, token) {
        let config = this.config
            // so 已经连接
        let initConfig = sessionStorage.getItem('config');
        if(initConfig){
            config = JSON.parse(initConfig)
        }
        let member_id = this.loginData.userData.member_id,
        port = config.port
        if (this.so && this.so.readyState == 1) {
            console.log("不要重复登录！");
            return { code: 301, data: "不要重复登录！" }
        }
        var that = this;
        that[_getHttp](
            config['h_url'] + "/getLoginKey",
            { token, port: config.port },
            function (data) {
                if (data.code == 200) {
                    var loginKey = data.data.loginKey;
                    var isForceLogin = data.data.isNeedForceLogin;
                    let url = "ws://" + config['e_url'] + ":" + 2345/* that.socket.port */;                   //url='ws://e.com:2345';
                    that.socket.storage.saveBySessionStorage('loginData', {key,token,member_id,port})
                    that[_getSo](url, key, loginKey, token, isForceLogin, that.loginData.sertype);
                }
            }
        );
    }
    /*socket连接 ，so监听事件*/
    [_getSo](url, key, loginKey, token, isForceLogin, sertype, callback, failCallback) {
        // sertype = '1'
        // callback ='1'
        // failCallback = '1'
        // console.log('url',url)
        // console.log('key',key)
        // console.log('loginKeyrl',loginKey)
        // console.log('token',token)
        // console.log('isForceLogin',isForceLogin)
        // console.log('sertype',sertype)
        // console.log('callback',callback)
        // console.log('failCallback',failCallback)
        for (let i in arguments) {
            if (arguments[i] == undefined || arguments[i] == '') {
                console.log("getSo,第" + i + "个参数不能为空！");
                return
            }
        }
        const that = this;
        if (this.so == null) {
            this.so = new WebSocket(url);
            this.so.onerror = () => { console.log("so连接失败！") };
            that.so.onopen = function () {
                if (that.so && that.so.readyState == 1) {
                    that.socket.receiverController.so = that.socket.receiverController.so = that.so;
                    const msg = that.socket.sendController.sendServerMsg("login", { key, loginKey, token, sertype, isForceLogin }, that.socket.controller.loginData.userData.member_id, (data) => {
                        if (data.body.code == 200) { callback && callback(data.body) } else { failCallback && failCallback(data.body); }
                    });
                    if (msg.code != 200) {
                        alert("消息创建失败！");
                        return { code: 301, data: '消息创建失败！' }
                    }
                    that.socket.sendController._sendMessage(msg.data.data.head.clientMsgId);
                }
            };
            this.so.onmessage = function (msg) {
                var data = JSON.parse(msg.data);
                if (data.head.ms == 1) {                            //服务端发送的数据
                    that.socket.receiverController.receiverMsg(data);
                } else {
                    that.socket.sendController._getServerReceiptMsg(data);   //回执消息的处理  
                }
            };
            this.so.onclose = function () {
                // console.log("离线!");
                if (that.userLoginStatus.leaveType != 1) { that.userLoginStatus.leaveType = 2; that.so = null; }
                that.userLoginStatus.isOnLine = false;
                that.loginData.onConnectClose ? that.loginData.onConnectClose() : '';               //socket断开回调 
                that.socket.heart.stop();                                                                    //停止心跳检测
                that.socket.friendObject.clear();
                that.socket.talkObject.clear();
            };
            this.socket.so = this.so
        }
    }
}